/*  This file is part of -_-.

    -_- is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    -_- is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with -_-.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2012-2013 Oliver Katz */

#include "lexer.h"
#include "error.h" // to prevent recursive definitions and stuff like that

namespace sleepyface
{
	namespace opal
	{
		Token::Token()
		{
			line = -1;
			col = -1;
		}

		Token::Token(string s, int l, int c)
		{
			line = l;
			col = c;
			content = s;
		}

		int Token::getLine()
		{
			return line;
		}

		int Token::getColumn()
		{
			return col;
		}

		string Token::get()
		{
			return content;
		}

		Lexer::Lexer()
		{
		}

		Lexer::Lexer(string d, string ig, string bq, string eq)
		{
			delims = d;
			ignores = ig;

			for (string::iterator i = ignores.begin(); i != ignores.end(); i++)
				if (d.find(*i) == string::npos)
					delims += *i;

			beginQuote = bq;
			endQuote = eq;
		}

		vector<Token> Lexer::lex(string page, string file)
		{
			vector<Token> rtn;
			string buf;
			bool q = false;

			int l = 0;
			int c = 0;

			for (string::iterator i = page.begin(); i != page.end(); i++)
			{
				if (beginQuote.find(*i) != string::npos && q == false)
				{
					q = true;
					buf += *i;
					continue;
				}
				else if (endQuote.find(*i) != string::npos && q == true)
				{
					q = false;
					buf += *i;
					rtn.push_back(Token(buf, l, c));
					buf = "";
					continue;
				}
				else if (beginQuote.find(*i) != string::npos || endQuote.find(*i) != string::npos)
				{
					if (!rtn.empty())
						error(rtn.back(), file, "mismatched quotation marks are nearby - OCD is acting up");
					else
						error(Token("", l, c), file, "mismatched quotation marks are nearby - OCD is acting up");
				}

				if (q == true)
				{
					buf += *i;
					continue;
				}

				if (delims.find(*i) != string::npos)
				{
					if (!buf.empty())
					{
						rtn.push_back(Token(buf, l, c));
						buf = "";
					}

					if (ignores.find(*i) == string::npos)
					{
						buf += *i;
						rtn.push_back(Token(buf, l, c));
						buf = "";
					}
				}
				else
				{
					buf += *i;
				}

				if (*i == '\n')
				{
					l++;
					c = 0;
				}
				else
				{
					c++;
				}
			}

			if (!buf.empty())
			{
				rtn.push_back(Token(buf, l, c));
			}

			return rtn;
		}
	}
}
